package org.jdns.jfreechess.server.commands;

import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import org.jdns.jfreechess.server.CommandHandler;
import org.jdns.jfreechess.server.CommandName;
import org.jdns.jfreechess.server.User;
import org.jdns.jfreechess.server.UserCommand;
import org.jdns.jfreechess.server.UserLocator;
import org.jdns.jfreechess.timeseal.TimesealedMessage;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

@CommandName(names = {"tell"})
public class TellCommand implements Command {
  @CommandHandler
  public void handleTellCommand(User user, UserLocator locator, @UserCommand String commandName,
      TimesealedMessage message) {
    List<String> params = ImmutableList.copyOf(Splitter.on(Pattern.compile("\\s+")).limit(3).split(message.getMessage()));
    if (params.size() < 3) {
      user.getChannel().write("Usage: " + commandName + " <whom> <what>");
      return;
    }

    String whom = params.get(1);
    Set<User> users;

    if (whom.endsWith("!")) {
      whom = whom.substring(0, whom.length() - 1);
      User foundUser = locator.getUserByName(whom);
      if (foundUser == null) {
        users = ImmutableSet.of();
      } else {
        users = ImmutableSet.of(foundUser);
      }
    } else {
      users = locator.findUsersByName(whom);
    }

    if (users.isEmpty()) {
      user.getChannel().write(whom + " is not logged in.");
    } else if (users.size() > 1) {
      user.getChannel().write(
          String.format("Ambiguous name %s:\n-- Matches: %d players --\n%s", whom, users.size(),
              Joiner.on('\t').join(Iterables.transform(users, User.NAME_FUNCTION))));
    } else {
      User targetUser = Iterables.getOnlyElement(users);
      String userMessage = String.format("(told %s)", targetUser.getName());
      String targetUserMessage = String.format("%s tells you: %s", user.getName(), params.get(2));

      if (targetUser.equals(user)) {
        user.getChannel().write(targetUserMessage + "\n" + userMessage);
      } else {
        user.getChannel().write(userMessage);
        targetUser.getChannel().write("\n" + targetUserMessage);
      }
    }
  }
}
